package com.buoy.base.aluminumpricespider.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.buoy.base.aluminumpricespider.model.BaseMetalPrice;
import com.buoy.base.aluminumpricespider.service.PriceService;
import com.buoy.base.aluminumpricespider.service.SpiderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/prices")
@CrossOrigin(origins = "*") // 允许跨域请求
@Slf4j
public class PriceController {

    private final PriceService priceService;
    private final SpiderService spiderService;

    @Autowired
    public PriceController(PriceService priceService, SpiderService spiderService) {
        this.priceService = priceService;
        this.spiderService = spiderService;
    }

    /**
     * 分页获取铝价数据
     * @param page 页码（从0开始）
     * @param size 每页大小
     * @param source 价格来源（可选，"shanghai"或"changjiang"）
     * @param startDate 开始日期（可选）
     * @param endDate 结束日期（可选）
     * @param manualUpdate 是否手动更新（可选）
     * @return 分页数据
     */
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> getPrices(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String source,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(required = false) String manualUpdate) {
        
        log.info("获取铝价数据，页码: {}, 大小: {}, 来源: {}, 开始日期: {}, 结束日期: {}, 手动更新: {}", 
                page, size, source, startDate, endDate, manualUpdate);
        
        Page<BaseMetalPrice> pricePage = priceService.getPrices(page, size, source, startDate, endDate, manualUpdate);
        
        Map<String, Object> response = new HashMap<>();
        response.put("content", pricePage.getRecords());
        response.put("totalElements", pricePage.getTotal());
        response.put("totalPages", pricePage.getPages());
        response.put("currentPage", pricePage.getCurrent() - 1);  // 转换为从0开始
        response.put("size", pricePage.getSize());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 手动爬取上海铝价
     * @return 爬取结果
     */
    @GetMapping("/crawl/shanghai")
    public ResponseEntity<Map<String, Object>> crawlShanghaiPrice() {
        log.info("手动触发爬取上海铝价");
        BaseMetalPrice price = spiderService.crawlShanghaiPrice();
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "上海铝价爬取成功");
        response.put("price", price);
        
        return ResponseEntity.ok(response);
    }

    /**
     * 手动爬取长江铝价
     * @return 爬取结果
     */
    @GetMapping("/crawl/changjiang")
    public ResponseEntity<Map<String, Object>> crawlChangjiangPrice() {
        log.info("手动触发爬取长江铝价");
        BaseMetalPrice price = spiderService.crawlChangjiangPrice();
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "长江铝价爬取成功");
        response.put("price", price);
        
        return ResponseEntity.ok(response);
    }

    /**
     * 手动更新铝价
     * @param priceSource 价格来源 ("shanghai" 或 "changjiang")
     * @param averagePrice 平均价格
     * @param priceDate 价格日期，格式为 yyyy-MM-dd
     * @return 更新结果
     */
    @PostMapping("/update")
    public ResponseEntity<Map<String, Object>> updatePrice(
            @RequestParam String priceSource,
            @RequestParam int averagePrice,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate priceDate) {
        
        log.info("手动更新{}铝价，日期: {}, 价格: {}", 
                priceSource.equals("shanghai") ? "上海" : "长江", 
                priceDate, averagePrice);
        
        BaseMetalPrice price = priceService.updatePrice(priceSource, averagePrice, priceDate);
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "铝价更新成功");
        response.put("price", price);
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 删除铝价记录
     * @param id 记录ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Map<String, Object>> deletePrice(@PathVariable Long id) {
        log.info("删除铝价记录，ID: {}", id);
        
        priceService.deletePrice(id);
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "铝价记录删除成功");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 批量删除铝价记录
     * @param ids 记录ID列表
     * @return 删除结果
     */
    @DeleteMapping("/batch")
    public ResponseEntity<Map<String, Object>> batchDeletePrices(@RequestBody List<Long> ids) {
        log.info("批量删除铝价记录，ID列表: {}", ids);
        
        for (Long id : ids) {
            priceService.deletePrice(id);
        }
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", "批量删除铝价记录成功");
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 获取指定来源的最新铝价
     * @param source 价格来源（"shanghai"或"changjiang"）
     * @return 最新的铝价数据
     */
    @GetMapping("/latest")
    public ResponseEntity<Map<String, Object>> getLatestPrice(@RequestParam String source) {
        log.info("获取最新{}铝价", source.equals("shanghai") ? "上海" : "长江");
        
        Page<BaseMetalPrice> pricePage = priceService.getPrices(0, 1, source, null, null, null);
        
        Map<String, Object> response = new HashMap<>();
        if (!pricePage.getRecords().isEmpty()) {
            response.put("success", true);
            response.put("data", pricePage.getRecords().get(0));
            return ResponseEntity.ok(response);
        } else {
            response.put("success", false);
            response.put("message", "未找到" + (source.equals("shanghai") ? "上海" : "长江") + "铝价数据");
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
        }
    }
    
    /**
     * 获取带前三天均价的铝价数据
     * @param source 价格来源（"shanghai"或"changjiang"）
     * @param date 价格日期（可选，默认为最新日期）
     * @return 带有前三天均价的铝价数据
     */
    @GetMapping("/avg/three-day")
    public ResponseEntity<Map<String, Object>> getPriceWithThreeDayAvg(
            @RequestParam String source,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
        
        log.info("获取带前三天均价的{}铝价，日期: {}", 
                source.equals("shanghai") ? "上海" : "长江", 
                date != null ? date : "最新");
        
        Map<String, Object> response = new HashMap<>();
        BaseMetalPrice price;
        
        try {
            if (date != null) {
                // 如果指定了日期，查询该日期的记录
                BaseMetalPrice existingPrice = priceService.getPrices(0, 1, source, date, date, null)
                        .getRecords().stream().findFirst().orElse(null);
                
                if (existingPrice == null) {
                    response.put("success", false);
                    response.put("message", "未找到指定日期的铝价数据");
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
                }
                
                price = priceService.calculateThreeDayAvgPrice(existingPrice);
            } else {
                // 如果未指定日期，查询最新记录
                Page<BaseMetalPrice> pricePage = priceService.getPrices(0, 1, source, null, null, null);
                
                if (pricePage.getRecords().isEmpty()) {
                    response.put("success", false);
                    response.put("message", "未找到" + (source.equals("shanghai") ? "上海" : "长江") + "铝价数据");
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
                }
                
                price = priceService.calculateThreeDayAvgPrice(pricePage.getRecords().get(0));
            }
            
            response.put("success", true);
            response.put("data", price);
            response.put("threeDayAvg", price.getThreeDayAvgPrice());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取带前三天均价的铝价出错: {}", e.getMessage(), e);
            response.put("success", false);
            response.put("message", "获取前三天均价信息失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取带前五天均价的铝价数据
     * @param source 价格来源（"shanghai"或"changjiang"）
     * @param date 价格日期（可选，默认为最新日期）
     * @return 带有前五天均价的铝价数据
     */
    @GetMapping("/avg/five-day")
    public ResponseEntity<Map<String, Object>> getPriceWithFiveDayAvg(
            @RequestParam String source,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
        
        log.info("获取带前五天均价的{}铝价，日期: {}", 
                source.equals("shanghai") ? "上海" : "长江", 
                date != null ? date : "最新");
        
        Map<String, Object> response = new HashMap<>();
        BaseMetalPrice price;
        
        try {
            if (date != null) {
                // 如果指定了日期，查询该日期的记录
                BaseMetalPrice existingPrice = priceService.getPrices(0, 1, source, date, date, null)
                        .getRecords().stream().findFirst().orElse(null);
                
                if (existingPrice == null) {
                    response.put("success", false);
                    response.put("message", "未找到指定日期的铝价数据");
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
                }
                
                price = priceService.calculateFiveDayAvgPrice(existingPrice);
            } else {
                // 如果未指定日期，查询最新记录
                Page<BaseMetalPrice> pricePage = priceService.getPrices(0, 1, source, null, null, null);
                
                if (pricePage.getRecords().isEmpty()) {
                    response.put("success", false);
                    response.put("message", "未找到" + (source.equals("shanghai") ? "上海" : "长江") + "铝价数据");
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
                }
                
                price = priceService.calculateFiveDayAvgPrice(pricePage.getRecords().get(0));
            }
            
            response.put("success", true);
            response.put("data", price);
            response.put("fiveDayAvg", price.getFiveDayAvgPrice());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取带前五天均价的铝价出错: {}", e.getMessage(), e);
            response.put("success", false);
            response.put("message", "获取前五天均价信息失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取前N天的铝价均价
     * @param source 价格来源（"shanghai"或"changjiang"）
     * @param days 天数（必须 > 0）
     * @param date 计算的基准日期（可选，默认为最新日期）
     * @return 前N天的铝价均价
     */
    @GetMapping("/avg/days")
    public ResponseEntity<Map<String, Object>> getPreviousDaysAvgPrice(
            @RequestParam String source,
            @RequestParam int days,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
        
        log.info("获取{}前{}天铝价均价，基准日期: {}", 
                source.equals("shanghai") ? "上海" : "长江", 
                days, date != null ? date : "最新");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            if (days <= 0) {
                response.put("success", false);
                response.put("message", "天数必须大于0");
                return ResponseEntity.badRequest().body(response);
            }
            
            LocalDate baseDate;
            if (date != null) {
                baseDate = date;
            } else {
                // 如果未指定日期，查询最新记录的日期
                Page<BaseMetalPrice> pricePage = priceService.getPrices(0, 1, source, null, null, null);
                
                if (pricePage.getRecords().isEmpty()) {
                    response.put("success", false);
                    response.put("message", "未找到" + (source.equals("shanghai") ? "上海" : "长江") + "铝价数据");
                    return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
                }
                
                baseDate = pricePage.getRecords().get(0).getPriceDate();
            }
            
            Integer avgPrice = priceService.getPreviousDaysAvgPrice(source, baseDate, days);
            
            if (avgPrice == null) {
                response.put("success", false);
                response.put("message", "计算均价失败，可能是数据不足");
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
            }
            
            response.put("success", true);
            response.put("source", source);
            response.put("baseDate", baseDate);
            response.put("days", days);
            response.put("avgPrice", avgPrice);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取前{}天铝价均价出错: {}", days, e.getMessage(), e);
            response.put("success", false);
            response.put("message", "获取均价失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
} 